import os
import subprocess
from pylint.lint import Run as pylint_run  # 使用 pylint 的 Python API 进行静态代码分析
from radon.complexity import cc_visit  # 用于计算代码的圈复杂度
from radon.metrics import mi_visit  # 用于计算代码的可维护性指数
import autopep8  # 用于自动修复 PEP 8 问题
from openai import OpenAI  # 用于调用 OpenAI 的 GPT 模型进行代码优化


# client = OpenAI(api_key=config["api_key"], base_url=config["base_url"])


def check_pep8(file_path):
    """
    使用 flake8 检查代码是否符合 PEP 8 规范。

    :param file_path: 要检查的 Python 文件路径。
    :return: 返回 flake8 的输出结果（字符串形式）。
    """
    print(f"检查 PEP 8 规范: {file_path}")
    # 使用 subprocess 调用 flake8 命令行工具
    result = subprocess.run(["flake8", file_path], capture_output=True, text=True)
    return result.stdout  # 返回 flake8 的输出

def check_pylint(file_path):
    """
    使用 pylint 进行静态代码分析。

    :param file_path: 要检查的 Python 文件路径。
    :return: 返回 pylint 发现的问题列表。
    """
    print(f"使用 pylint 进行静态代码分析: {file_path}")
    # 使用 pylint 的 Python API 运行静态代码分析
    results = pylint_run([file_path], exit=False)
    issues = []
    if results.linter.stats['by_msg']:  # 如果有错误或警告
        for msg_id, count in results.linter.stats['by_msg'].items():
            issues.append(f"发现 {count} 个 {msg_id} 问题。")
    return issues

def check_code_complexity(file_path):
    """
    使用 radon 检查代码复杂度。

    :param file_path: 要检查的 Python 文件路径。
    :return: 返回代码复杂度问题的列表。
    """
    print(f"检查代码复杂度: {file_path}")
    with open(file_path, "r") as f:
        code = f.read()  # 读取文件内容
    # 计算圈复杂度
    complexity = cc_visit(code)
    issues = []
    for block in complexity:
        if block.complexity > 5:  # 圈复杂度大于 5 时认为需要优化
            issues.append(f"函数/方法 '{block.name}' 的圈复杂度为 {block.complexity}，建议重构。")
    return issues

def check_unused_imports(file_path):
    """
    检查未使用的导入。

    :param file_path: 要检查的 Python 文件路径。
    :return: 返回 pylint 的输出结果（字符串形式）。
    """
    print(f"检查未使用的导入: {file_path}")
    # 使用 subprocess 调用 pylint 命令行工具，仅检查未使用的导入
    result = subprocess.run(["pylint", "--disable=all", "--enable=unused-import", file_path], capture_output=True, text=True)
    return result.stdout

def fix_pep8(file_path, output_path):
    """
    使用 autopep8 自动修复 PEP 8 问题。

    :param file_path: 要修复的 Python 文件路径。
    :param output_path: 修复后的文件保存路径。
    """
    with open(file_path, "r") as f:
        code = f.read()  # 读取文件内容
    # 使用 autopep8 自动修复代码
    fixed_code = autopep8.fix_code(code)
    with open(output_path, "w") as f:
        f.write(fixed_code)  # 将修复后的代码写入新文件
    print(f"已修复 PEP 8 问题，优化后的代码保存到: {output_path}")

def ai_optimize_code(file_path, output_path):
    """
    使用 OpenAI GPT 模型优化代码。

    :param file_path: 要优化的 Python 文件路径。
    :param output_path: 优化后的文件保存路径。
    """
    with open(file_path, "r") as f:
        code = f.read()  # 读取文件内容

    # 调用 OpenAI API
    response = client.chat.completions.create(
        model="gpt-4",  # 使用 GPT-4 模型
        messages=[
            {"role": "system", "content": "你是一个代码优化助手，请优化以下 Python 代码。"},
            {"role": "user", "content": f"请优化以下 Python 代码：\n\n{code}"}
        ],
        max_tokens=1000,  # 设置最大 token 数
        temperature=0.5  # 设置生成文本的随机性
    )

    # 获取优化后的代码
    optimized_code = response["choices"][0]["message"]["content"]
    with open(output_path, "w") as f:
        f.write(optimized_code)  # 将优化后的代码写入新文件
    print(f"已使用 AI 优化代码，优化后的代码保存到: {output_path}")

def code_review_and_optimize(directory, output_directory):
    """
    对指定目录下的所有 Python 文件进行代码审查和优化。

    :param directory: 要审查的代码目录。
    :param output_directory: 优化后的代码保存目录。
    """
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)  # 如果输出目录不存在，则创建

    # 遍历目录中的所有文件
    for root, _, files in os.walk(directory):
        for file in files:
            if file.endswith(".py"):  # 仅处理 Python 文件
                file_path = os.path.join(root, file)  # 文件完整路径
                output_path = os.path.join(output_directory, file)  # 输出文件路径

                print(f"\n正在审查文件: {file_path}")

                # 检查 PEP 8 规范
                pep8_issues = check_pep8(file_path)
                if pep8_issues:
                    print("PEP 8 问题：")
                    print(pep8_issues)
                    fix_pep8(file_path, output_path)  # 自动修复 PEP 8 问题
                else:
                    print("PEP 8 检查通过，未发现问题。")

                # 使用 pylint 进行静态代码分析
                pylint_issues = check_pylint(file_path)
                if pylint_issues:
                    print("pylint 问题：")
                    for issue in pylint_issues:
                        print(issue)
                else:
                    print("pylint 检查通过，未发现问题。")

                # 检查代码复杂度
                complexity_issues = check_code_complexity(file_path)
                if complexity_issues:
                    print("代码复杂度问题：")
                    for issue in complexity_issues:
                        print(issue)
                else:
                    print("代码复杂度检查通过，未发现问题。")

                # 检查未使用的导入
                unused_imports = check_unused_imports(file_path)
                if unused_imports:
                    print("未使用的导入：")
                    print(unused_imports)
                else:
                    print("未发现未使用的导入。")

                # 使用 AI 进行高级优化
                ai_optimize_code(file_path, output_path)

                print("-" * 80)  # 分隔线

if __name__ == "__main__":
    # 指定要审查和优化的目录
    target_directory = "D:\code\git-change-analyzer-app"  # 替换为你的代码目录
    output_directory = "D:\code\git-change-analyzer-app-new"  # 替换为优化后的代码保存目录
    code_review_and_optimize(target_directory, output_directory)